package cz.ctu.guiproject.client.xml;

import guiproject.client.view.Event;

import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

import org.xmlpull.v1.XmlSerializer;

import android.util.Log;
import android.util.Xml;
import cz.ctu.guiproject.client.messaging.DisconnectRequest;
import cz.ctu.guiproject.client.messaging.InitRequest;
import cz.ctu.guiproject.client.messaging.UIRequest;
import cz.ctu.guiproject.client.resources.InstalledComponent;
import static cz.ctu.guiproject.client.resources.constants.Constants.*;
import static cz.ctu.guiproject.client.resources.constants.Logger.*;

public final class XmlEncodeFactory {

	public static String encodeConfig(String ip, int port) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);
			// open tag: <init-request>
			xmlSerializer.startTag("", SAVED_CONFIG);

			xmlSerializer.startTag("", SERVER_IP);
			xmlSerializer.text(ip);
			xmlSerializer.endTag("", SERVER_IP);

			xmlSerializer.startTag("", SERVER_PORT);
			xmlSerializer.text(String.valueOf(port));
			xmlSerializer.endTag("", SERVER_PORT);

			// close tag: </init-request>
			xmlSerializer.endTag("", SAVED_CONFIG);
			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

	public static String encodeDisconnectRequest(DisconnectRequest disconnectRequest) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);
			// open tag: <init-request>
			xmlSerializer.startTag("", SERVER_DISCONNECT_REQUEST);
			// close tag: </init-request>
			xmlSerializer.endTag("", SERVER_DISCONNECT_REQUEST);
			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

	public static String encodePropagateUIUpdate(String viewId, String attrName, String attrValue) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);
			// start tag <propagate-ui-update>
			xmlSerializer.startTag("", SERVER_PROPAGATE_UI_UPDATE);

			// start tag <viewId>
			xmlSerializer.startTag("", SERVER_VIEW_ID);
			xmlSerializer.text(viewId);
			// end tag </viewId>
			xmlSerializer.endTag("", SERVER_VIEW_ID);

			// start tag <attribute-name>
			xmlSerializer.startTag("", SERVER_ATTR_NAME);
			xmlSerializer.text(attrName);
			// end tag </attribute-name>
			xmlSerializer.endTag("", SERVER_ATTR_NAME);

			// start tag <attribute-value>
			xmlSerializer.startTag("", SERVER_ATTR_VALUE);
			xmlSerializer.text(attrValue);
			// end tag </attribute-value>
			xmlSerializer.endTag("", SERVER_ATTR_VALUE);

			// end tag </propagate-ui-update>
			xmlSerializer.endTag("", SERVER_PROPAGATE_UI_UPDATE);

			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

	public static String encodeEvent(Event event) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);
			// open tag: <event-occured>
			xmlSerializer.startTag("", SERVER_EVENT_OCCURED);
			// open tag: <eventId>
			xmlSerializer.startTag("", SERVER_EVENT_ID);
			xmlSerializer.text(event.getEventId());
			// close tag: </eventId>
			xmlSerializer.endTag("", SERVER_EVENT_ID);
			// open tag: <keys>
			xmlSerializer.startTag("", SERVER_EVENT_KEYS);
			StringBuilder sb = new StringBuilder();
			final Object[] keys = event.getKeys();
			for (int i = 0; i < keys.length; ++i) {
				if (i != 0) {
					sb.append(COMMA);
				}
				sb.append(keys[i]);
			}
			xmlSerializer.text(sb.toString());
			// close tag: </keys>
			xmlSerializer.endTag("", SERVER_EVENT_KEYS);
			// open tag: <values>
			xmlSerializer.startTag("", SERVER_EVENT_VALUES);
			sb = new StringBuilder();
			final Object[] values = event.getValues();
			for (int i = 0; i < values.length; ++i) {
				if (i != 0) {
					sb.append(COMMA);
				}
				sb.append(values[i]);
			}
			xmlSerializer.text(sb.toString());
			// close tag: </values>
			xmlSerializer.endTag("", SERVER_EVENT_VALUES);
			// close tag: </event-occured>
			xmlSerializer.endTag("", SERVER_EVENT_OCCURED);
			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

	public static String encodeInitRequest(InitRequest initRequest) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);
			// open tag: <init-request>
			xmlSerializer.startTag("", SERVER_INIT_REQUEST);
			// open tag: <device-name>
			xmlSerializer.startTag("", DEVICE_NAME);
			xmlSerializer.text(initRequest.getDeviceName());
			// close tag: </device-name>
			xmlSerializer.endTag("", DEVICE_NAME);

			// open tag: <installed-components>
			xmlSerializer.startTag("", INSTALLED_COMPONENTS);

			final StringBuilder sb = new StringBuilder();
			final String[] arr = initRequest.getInstalledComponents();
			for (int i = 0; i < arr.length;) {
				if (i != 0) {
					sb.append(", ");
				}
				sb.append(arr[i++]);
				sb.append(", ");
				sb.append(arr[i++]);
			}
			xmlSerializer.text(sb.toString());

			// close tag: </installed-components>
			xmlSerializer.endTag("", INSTALLED_COMPONENTS);
			// close tag: </init-request>
			xmlSerializer.endTag("", SERVER_INIT_REQUEST);
			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

	public static String encodeUIRequest(UIRequest uiRequest) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);
			// open tag: <init-request>
			xmlSerializer.startTag("", SERVER_UI_REQUEST);
			// close tag: </init-request>
			xmlSerializer.endTag("", SERVER_UI_REQUEST);
			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

	public static String encodeInstalledComponents(List<InstalledComponent> components) {
		final XmlSerializer xmlSerializer = Xml.newSerializer();
		final StringWriter writer = new StringWriter();

		try {
			xmlSerializer.setOutput(writer);
			// start DOCUMENT
			xmlSerializer.startDocument(UTF_8, true);

			xmlSerializer.startTag("", SERVER_INSTALLED_COMPONENTS);

			for (InstalledComponent comp : components) {
				xmlSerializer.startTag("", SERVER_INSTALLED_COMPONENT);

				xmlSerializer.startTag("", SERVER_INSTALLED_COMPONENT_NAME);
				xmlSerializer.text(comp.getName());
				xmlSerializer.endTag("", SERVER_INSTALLED_COMPONENT_NAME);

				xmlSerializer.startTag("", SERVER_INSTALLED_COMPONENT_VERSION);
				xmlSerializer.text(String.valueOf(comp.getVersion()));
				xmlSerializer.endTag("", SERVER_INSTALLED_COMPONENT_VERSION);

				xmlSerializer.endTag("", SERVER_INSTALLED_COMPONENT);
			}

			xmlSerializer.endTag("", SERVER_INSTALLED_COMPONENTS);

			// end DOCUMENT
			xmlSerializer.endDocument();

		} catch (IllegalArgumentException e) {
			Log.e(TAG, e.getMessage());
		} catch (IllegalStateException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		}

		return writer.toString();
	}

}
